home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2009 December / maximum-cd-2009-12.iso / DiscContents / gimp-2.7.0-i686-setup.exe / {app} / share / gimp / 2.0 / scripts / spyrogimp.scm < prev    next >
Encoding:
GIMP Script-Fu Script  |  2009-08-19  |  12.0 KB  |  356 lines

  1. ; spyrogimp.scm -*-scheme-*-
  2. ; Draws Spirographs, Epitrochoids and Lissajous Curves.
  3. ; More info at http://www.wisdom.weizmann.ac.il/~elad/spyrogimp/
  4. ; Version 1.2
  5. ;
  6. ; Copyright (C) 2003 by Elad Shahar <elad@wisdom.weizmann.ac.il>
  7. ;
  8. ; This program is free software: you can redistribute it and/or modify
  9. ; it under the terms of the GNU General Public License as published by
  10. ; the Free Software Foundation; either version 3 of the License, or
  11. ; (at your option) any later version.
  12. ;
  13. ; This program is distributed in the hope that it will be useful,
  14. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. ; GNU General Public License for more details.
  17. ;
  18. ; You should have received a copy of the GNU General Public License
  19. ; along with this program.  If not, see <http://www.gnu.org/licenses/>.
  20.  
  21.  
  22. ; This routine is invoked by a dialog.
  23. ; It is the main routine in this file.
  24. (define (script-fu-spyrogimp img drw
  25.                              type shape
  26.                              oteeth iteeth
  27.                              margin hole-ratio start-angle
  28.                              tool brush
  29.                              color-method color grad)
  30.  
  31.   ; Internal function to draw the spyro.
  32.   (define (script-fu-spyrogimp-internal img drw
  33.                x1 y1 x2 y2   ; Bounding box.
  34.                type          ; = 0 (Spirograph), 1 (Epitrochoid), 2(Lissajous) .
  35.                shape         ; = 0 (Circle), 1 (Frame), >2 (Polygons) .
  36.                oteeth iteeth ; Outer and inner teeth.
  37.                margin hole-ratio
  38.                start-angle   ; 0 <= start-angle < 360 .
  39.                tool          ; = 0 (Pencil), 1 (Brush), 2 (Airbrush) .
  40.                brush
  41.                color-method  ; = 0 (Single color), 1 (Grad. Loop Sawtooth),
  42.                              ;   2 (Grad. Loop triangle) .
  43.                color         ; Used when color-method = Single color .
  44.                grad          ; Gradient used in Gradient color methods.
  45.           )
  46.  
  47.  
  48.     ; This function returns a list of samples according to the gradient.
  49.     (define (get-gradient steps color-method grad)
  50.       (if (= color-method 1)
  51.           ; option 1
  52.           ; Just return the gradient
  53.           (gimp-gradient-get-uniform-samples grad (min steps 50) FALSE)
  54.  
  55.           ; option 2
  56.           ; The returned list is such that the gradient appears two times, once
  57.           ; in the normal order and once in reverse. This way there are no color
  58.           ; jumps if we go beyond the edge
  59.           (let* (
  60.                 ; Sample the gradient into array "gr".
  61.                 (gr (gimp-gradient-get-uniform-samples grad
  62.                                                        (/ (min steps 50) 2)
  63.                                                        FALSE))
  64.  
  65.                 (grn (car gr))  ; length of sample array.
  66.                 (gra (cadr gr)) ; array of color samples (R1,G1,B1,A1, R2,....)
  67.  
  68.                 ; Allocate array gra-new of size  (2 * grn) - 8,
  69.                 ; but since each 4 items is actually one (RGBA) tuple,
  70.                 ; it contains 2x - 2 entries.
  71.                 (grn-new (+ grn grn -8))
  72.                 (gra-new (cons-array grn-new 'double))
  73.  
  74.                 (gr-index 0)
  75.                 (gr-index2 0)
  76.                 )
  77.  
  78.             ; Copy original array gra to gra_new.
  79.             (while (< gr-index grn)
  80.                (aset gra-new gr-index (aref gra gr-index))
  81.                (set! gr-index (+ 1 gr-index))
  82.             )
  83.  
  84.             ; Copy second time, but in reverse
  85.             (set! gr-index2 (- gr-index 8))
  86.             (while (< gr-index grn-new)
  87.                (aset gra-new gr-index (aref gra gr-index2))
  88.                (set! gr-index (+ 1 gr-index))
  89.                (set! gr-index2 (+ 1 gr-index2))
  90.  
  91.                (if (= (fmod gr-index 4) 0)
  92.                  (set! gr-index2 (- gr-index2 8))
  93.                )
  94.             )
  95.  
  96.             ; Return list.
  97.             (list grn-new gra-new)
  98.           )
  99.       )
  100.     )
  101.  
  102.  
  103.     (let* (
  104.           (steps (+ 1 (lcm oteeth iteeth)))
  105.           (*points* (cons-array (* steps 2) 'double))
  106.  
  107.           (ot 0)                         ; current outer tooth
  108.           (cx 0)                         ; Current x,y
  109.           (cy 0)
  110.  
  111.           ; If its a polygon or frame, how many sides does it have.
  112.           (poly (if (= shape 1) 4   ; A frame has four sides.
  113.                                 (if (> shape 1) (+ shape 1) 0)))
  114.  
  115.           (2pi (* 2 *pi*))
  116.  
  117.           (drw-width (- x2 x1))
  118.           (drw-height (- y2 y1))
  119.           (half-width (/ drw-width 2))
  120.           (half-height (/ drw-height 2))
  121.           (midx (+ x1 half-width))
  122.           (midy (+ y1 half-height))
  123.  
  124.           (hole (* hole-ratio
  125.                    (- (/ (min drw-width drw-height) 2) margin)
  126.                 )
  127.           )
  128.           (irad (+ hole margin))
  129.  
  130.           (radx (- half-width irad))  ;
  131.           (rady (- half-height irad)) ;
  132.  
  133.           (gradt (get-gradient steps color-method grad))
  134.           (grada (cadr gradt)) ; Gradient array.
  135.           (gradn (car gradt))  ; Number of entries of gradients.
  136.  
  137.           ; Indexes
  138.           (grad-index 0)  ; for array: grada
  139.           (point-index 0) ; for array: *points*
  140.           (index 0)
  141.           )
  142.  
  143.       ; Do one step of the loop.
  144.       (define (calc-and-step!)
  145.         (let* (
  146.               (oangle (* 2pi (/ ot oteeth)) )
  147.               (shifted-oangle (+ oangle (* 2pi (/ start-angle 360))) )
  148.               (xfactor (cos shifted-oangle))
  149.               (yfactor (sin shifted-oangle))
  150.               (lenfactor 1)
  151.               (ofactor (/ (+ oteeth iteeth) iteeth))
  152.  
  153.               ; The direction of the factor changes according
  154.               ; to whether the type is a sypro or an epitcorhoid.
  155.               (mfactor (if (= type 0) (- ofactor) ofactor))
  156.               )
  157.  
  158.           ; If we are drawing a polygon then compute a contortion
  159.           ; factor "lenfactor" which deforms the standard circle.
  160.           (if (> poly 2)
  161.             (let* (
  162.                   (pi4 (/ *pi* poly))
  163.                   (pi2 (* pi4 2))
  164.  
  165.                   (oanglemodpi2 (fmod (+ oangle
  166.                                         (if (= 1 (fmod poly 2))
  167.                                            0 ;(/ pi4 2)
  168.                                            0
  169.                                         )
  170.                                       )
  171.                                       pi2))
  172.                   )
  173.  
  174.                   (set! lenfactor (/ ( if (= shape 1) 1 (cos pi4) )
  175.                                      (cos
  176.                                        (if (< oanglemodpi2 pi4)
  177.                                          oanglemodpi2
  178.                                          (- pi2 oanglemodpi2)
  179.                                        )
  180.                                      )
  181.                                   )
  182.                   )
  183.             )
  184.           )
  185.  
  186.           (if (= type 2)
  187.             (begin  ; Lissajous
  188.               (set! cx (+ midx
  189.                           (* half-width (cos shifted-oangle)) ))
  190.               (set! cy (+ midy
  191.                           (* half-height (cos (* mfactor oangle))) ))
  192.             )
  193.             (begin  ; Spyrograph or Epitrochoid
  194.              (set! cx (+ midx
  195.                          (* radx xfactor lenfactor)
  196.                          (* hole (cos (* mfactor oangle) ) ) ))
  197.              (set! cy (+ midy
  198.                          (* rady yfactor lenfactor)
  199.                          (* hole (sin (* mfactor oangle) ) ) ))
  200.             )
  201.           )
  202.  
  203.         ;; Advance teeth
  204.         (set! ot (+ ot 1))
  205.         )
  206.       )
  207.  
  208.  
  209.       ;; Draw all the points in *points* with appropriate tool.
  210.       (define (flush-points len)
  211.         (if (= tool 0)
  212.           (gimp-pencil drw len *points*)              ; Use pencil
  213.           (if (= tool 1)
  214.             (gimp-paintbrush-default drw len *points*); use paintbrush
  215.             (gimp-airbrush-default drw len *points*)  ; use airbrush
  216.           )
  217.         )
  218.  
  219.         ; Reset points array, but copy last point to first
  220.         ; position so it will connect the next time.
  221.         (aset *points* 0 (aref *points* (- point-index 2)))
  222.         (aset *points* 1 (aref *points* (- point-index 1)))
  223.         (set! point-index 2)
  224.       )
  225.  
  226.    ;;
  227.    ;; Execution starts here.
  228.    ;;
  229.  
  230.       (gimp-context-push)
  231.  
  232.       (gimp-image-undo-group-start img)
  233.  
  234.       ; Set new color, brush, opacity, paint mode.
  235.       (gimp-context-set-foreground color)
  236.       (gimp-context-set-brush (car brush))
  237.       (gimp-context-set-opacity (* 100 (car (cdr brush))))
  238.       (gimp-context-set-paint-mode (car (cdr (cdr (cdr brush)))))
  239.  
  240.       (gimp-progress-set-text _"Rendering Spyro")
  241.  
  242.       (while (< index steps)
  243.  
  244.           (calc-and-step!)
  245.  
  246.           (aset *points* point-index cx)
  247.           (aset *points* (+ point-index 1) cy)
  248.           (set! point-index (+ point-index 2))
  249.  
  250.           ; Change color and draw points if using gradient.
  251.           (if (< 0 color-method)  ; use gradient.
  252.              (if (< (/ (+ grad-index 4) gradn) (/ index steps))
  253.                (begin
  254.                 (gimp-context-set-foreground
  255.                   (list
  256.                     (* 255 (aref grada grad-index))
  257.                     (* 255 (aref grada (+ 1 grad-index)) )
  258.                     (* 255 (aref grada (+ 2 grad-index)) )
  259.                   )
  260.                 )
  261.                 (gimp-context-set-opacity (* 100 (aref grada (+ 3 grad-index) ) )  )
  262.                 (set! grad-index (+ 4 grad-index))
  263.  
  264.                 ; Draw points
  265.                 (flush-points point-index)
  266.                )
  267.              )
  268.           )
  269.  
  270.           (set! index (+ index 1))
  271.  
  272.       (if (= 0 (modulo index 16))
  273.           (gimp-progress-update (/ index steps))
  274.       )
  275.       )
  276.  
  277.       ; Draw remaining points.
  278.       (flush-points point-index)
  279.  
  280.       (gimp-progress-update 1.0)
  281.  
  282.       (gimp-image-undo-group-end img)
  283.       (gimp-displays-flush)
  284.  
  285.       (gimp-context-pop)
  286.     )
  287.   )
  288.  
  289.   (let* (
  290.         ; Get current selection to determine where to draw.
  291.         (bounds (cdr (gimp-selection-bounds img)))
  292.         (x1 (car bounds))
  293.         (y1 (cadr bounds))
  294.         (x2 (caddr bounds))
  295.         (y2 (car (cdddr bounds)))
  296.         )
  297.  
  298.     (set! oteeth (trunc (+ oteeth 0.5)))
  299.     (set! iteeth (trunc (+ iteeth 0.5)))
  300.  
  301.     (script-fu-spyrogimp-internal img drw
  302.              x1 y1 x2 y2
  303.              type shape
  304.              oteeth iteeth
  305.              margin hole-ratio start-angle
  306.              tool brush
  307.              color-method color grad)
  308.   )
  309. )
  310.  
  311.  
  312.  
  313. (script-fu-register "script-fu-spyrogimp"
  314.   _"_Spyrogimp..."
  315.   _"Add Spirographs, Epitrochoids, and Lissajous Curves to the current layer"
  316.   "Elad Shahar <elad@wisdom.weizmann.ac.il>"
  317.   "Elad Shahar"
  318.   "June 2003"
  319.   "RGB*, INDEXED*, GRAY*"
  320.   SF-IMAGE       "Image"         0
  321.   SF-DRAWABLE    "Drawable"      0
  322.  
  323.   SF-OPTION     _"Type"          '(_"Spyrograph"
  324.                                    _"Epitrochoid"
  325.                                    _"Lissajous")
  326.   SF-OPTION     _"Shape"         '(_"Circle"
  327.                                     _"Frame"
  328.                                    _"Triangle"
  329.                                    _"Square"
  330.                                    _"Pentagon"
  331.                                    _"Hexagon"
  332.                                    _"Polygon: 7 sides"
  333.                                    _"Polygon: 8 sides"
  334.                                    _"Polygon: 9 sides"
  335.                                    _"Polygon: 10 sides")
  336.   SF-ADJUSTMENT _"Outer teeth"   '(86 1 120 1 10 0 0)
  337.   SF-ADJUSTMENT _"Inner teeth"   '(70 1 120 1 10 0 0)
  338.   SF-ADJUSTMENT _"Margin (pixels)" '(0 -10000 10000 1 10 0 1)
  339.   SF-ADJUSTMENT _"Hole ratio"    '(0.4 0.0 1.0 0.01 0.1 2 0)
  340.   SF-ADJUSTMENT _"Start angle"   '(0 0 359 1 10 0 0)
  341.  
  342.   SF-OPTION     _"Tool"          '(_"Pencil"
  343.                                    _"Brush"
  344.                                    _"Airbrush")
  345.   SF-BRUSH      _"Brush"         '("Circle (01)" 1.0 -1 0)
  346.  
  347.   SF-OPTION     _"Color method"  '(_"Solid Color"
  348.                                    _"Gradient: Loop Sawtooth"
  349.                                    _"Gradient: Loop Triangle")
  350.   SF-COLOR      _"Color"          "black"
  351.   SF-GRADIENT   _"Gradient"       "Deep Sea"
  352. )
  353.  
  354. (script-fu-menu-register "script-fu-spyrogimp"
  355.                          "<Image>/Filters/Render")
  356.